﻿package igz.fleaxy.pattern 
{
	import flash.utils.getDefinitionByName;
	import flash.utils.getQualifiedClassName;
	import igz.fleaxy.debug.Console;
	import igz.fleaxy.util.DataTableUtil;
	/**
	 * @author Intelygenz | www.intelygenz.com
	 * 
	 * Factoria que crea los DTOS a partir de los datos de entrada (Un json o un xml)
	 * 
	 */
	public class AbstractFactory {

		protected var _DataTable:Object;
		public function get $DataTable() : Object {
			return _DataTable;
		}

		protected var _DtoType     : Class;
		public function get $DtoType() : Class {
			return _DtoType;
		}

		[ArrayElementType("igz.fleaxy.pattern.Dto")]
		protected var _Dtos : Array;
		public function get $Dtos() : Array {
			return _Dtos;
		}

		public function AbstractFactory(p_dtoType:Class) {
			_DtoType = p_dtoType;
			_Dtos = [];
		}

		/**
		 * Función que a partir de un XML y un "label" o nombre de los elementos que corresponden al DTO genera un listado de DTOS
		 * con los datos del XML
		 * 
		 * @param	p_xml XML con los datos
		 * @param	p_label etiqueta con el nombre del elemento referente a los dto's
		 */
		public function $LoadFromXML( p_xml:XML, p_label:String, p_dateTimeFormat:String = null ) : void {
			_Dtos = new Array();

			var dto : Dto;
			var xmlDto : XML;
			var xmlDtos : XMLList = p_xml.elements( p_label );
			for each ( xmlDto in xmlDtos ) {
				dto = new _DtoType( this );
				dto._LoadFromXML( xmlDto, p_dateTimeFormat );
				_Dtos.push( dto );
			}
		}

		/**
		 * Función que apartir de un JSON y una etiqueta con el nombre de los elementos DTO genera un listado de DTOS
		 * 
		 * @param	p_json Objeto JSON con todos los elementos
		 * @param	p_label Etiqueta con el nombre de los elementos para el json
		 */
		public function $LoadFromJSON( p_json:Object, p_labelBlock:String, p_dateTimeFormat:String = null ) : Array {
			var dtos : Array;
			
			var rootTag : String = "";
			for ( rootTag in p_json ) { break; }
			if ( rootTag == "" ) {
				trace ("[AbstractFactory.$LoadFromJSON] El json devuelto esta vacio. p_label["+ p_labelBlock +"]");
			}
			else {
				var blocks : Object = p_json[rootTag] as Object;
				if ( blocks.hasOwnProperty(p_labelBlock) ) {
					
					dtos = $LoadFromDataTable( blocks[p_labelBlock], p_dateTimeFormat );
				}
				else {
					trace ("[AbstractFactory.$LoadFromJSON] El json devuelto no contine un bloque con el label '" + p_labelBlock + "'\n"
							+ Console.$DebugJson( p_json[rootTag] )
							);
				}
			}
			
			return dtos;
		}
		
		public function $LoadFromDataTable( p_dataTable:Object, p_dateTimeFormat:String = null ) : Array {
			var dtos : Array = new Array();
			
			if ( DataTableUtil.$IsDataTable(p_dataTable) ) {
				_DataTable = p_dataTable;
				
				var columns:Array = [].concat(_DataTable[DataTableUtil.$COLUMNS_LABEL] as Array);
				var columnName:String = "";
				var columnNameOld:String="";
				if ( columns.length > 0 ) {
					columnName = columns[0];
				}

				if(columnName.indexOf("$")==-1) {
					for each ( columnName in columns) {
						columnNameOld = columnName;
						columnName = columnName.substring(0, 1).toUpperCase() + columnName.substr(1);
						if ( columnName.indexOf("@")!=-1 ) {
							columnName = columnName.substring(0, columnName.indexOf("@"));
						}
						columnName = "$" + columnName;
						_DataTable[DataTableUtil.$COLUMNS_LABEL][ _DataTable[DataTableUtil.$COLUMNS_LABEL].indexOf(columnNameOld) ] = columnName;
					}
				}

				var dto : Dto;
				var index : uint;
				var rows : Array = _DataTable[ DataTableUtil.$ROWS_LABEL ];
				for ( index = 0; index < rows.length; index++ ) {
					dto = new _DtoType();
					dto.$LoadFromJSON( _DataTable, index, p_dateTimeFormat );
					dtos.push( dto );
				}
			}
			else {
				trace ("[AbstractFactory.$LoadFromJSON] El DataTable indicado no es correcto\n["
						+ Console.$DebugJson( p_dataTable )
						+ "]"
					  );
			}
			
			_Dtos = dtos;
			
			return dtos;
		}

	}
	
}